/*
 ------------------------------------------------------------------------------
 Copyright (C) 2013 Eternal Games.

 This file is part of the GLQuake source code.

 The GLQuake source code is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or (at your
 option) any later version.

 The GLQuake source code is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 more details.

 You should have received a copy of the GNU General Public License along with
 the GLQuake source code; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 ------------------------------------------------------------------------------
*/


//
// r_public.h - public header to all other files
//


#ifndef __R_PUBLIC_H__
#define __R_PUBLIC_H__


/*
 ==============================================================================

 Renderer:

 The renderer is responsible for managing the screen, which can have multiple
 3D and 2D drawing done on it.

 All drawing is done to a 640x480 virtual screen resolution and will be
 automatically scaled to the real screen resolution and corrected for the
 screen aspect ratio.

 ==============================================================================
*/

// Loads and prepares the given map for rendering
void			R_LoadMap (const char *name);

// Loads and prepares post-process effects for the given map
void			R_LoadPostProcess (const char *name);

// Loads and registers the given model
model_t *		R_RegisterModel (const char *name);

// Loads and registers the given material
material_t *	R_RegisterMaterial (const char *name);
material_t *	R_RegisterMaterialLight (const char *name);
material_t *	R_RegisterMaterialNoMip (const char *name);

// Returns the number of frames for the given model
int					R_ModelFrames (model_t *model);

// Scenes can be allocated and freed as needed.
// The client will allocate the primary scene for rendering the game view, but
// other parts of the program can also allocate scenes for other uses, like
// drawing 3D items in the HUD, or displaying models in a GUI.
scene_t *		R_AllocScene (bool primary);
void			R_FreeScene (scene_t *scene);

// Entities, lights, and particles must be added to a given scene to determine
// what will be drawn for a given view. Most update work is deferred until it
// is determined that it is actually needed for a given view.
// Nothing is drawn until R_RenderScene is called.
int				R_AddRenderEntity (scene_t *scene, const renderEntity_t *renderEntity);
void			R_UpdateRenderEntity (scene_t *scene, int entityHandle, const renderEntity_t *renderEntity);
void			R_RemoveRenderEntity (scene_t *scene, int entityHandle);

int				R_AddRenderLight (scene_t *scene, const renderLight_t *renderLight);
void			R_UpdateRenderLight (scene_t *scene, int lightHandle, const renderLight_t *renderLight);
void			R_RemoveRenderLight (scene_t *scene, int lightHandle);

int				R_AddRenderParticle (scene_t *scene, const renderParticle_t *renderParticle);
void			R_UpdateRenderParticle (scene_t *scene, int particleHandle, const renderParticle_t *renderParticle);
void			R_RemoveRenderParticle (scene_t *scene, int particleHandle);

// Removes all decals from the model of the given entity
void			R_RemoveDecals (scene_t *scene, int entityHandle);

// Generates lists of static shadows and interactions and precaches the given
// lights.
// If this isn't called after loading a map, all the world shadows and
// interactions will be dynamically generated.
void			R_PrecacheLights (scene_t *scene, int numRenderLights, const renderLight_t *renderLights);

// Rendering a scene may actually render multiple views for skies, mirrors,
// portals, and remote cameras.
// If primaryView is false, the world map will be ignored completely, which is
// useful for rendering things like GUI models.
void			R_RenderScene (scene_t *scene, const renderView_t *renderView, bool primaryView);

// Captures the render output to the given texture.
// Returns false if the texture wasn't found or couldn't be dynamically
// modified.
bool			R_CaptureRenderToTexture (const char *name);

// Updates the given texture's image. The image data must be in RGBA format.
// Does not allocate memory, so the image pointer must remain valid for the
// rest of the frame.
// Returns false if the texture wasn't found or couldn't be dynamically
// modified.
bool			R_UpdateTextureImage (const char *name, const byte *image, int width, int height);

// 2D drawing just involves color and material parameters setting and axial
// image subsections.
// The horizontal / vertical adjustment parameters are used to control the
// automatic coordinate scaling and aspect ratio correction on each axis
// separately.
void			R_SetColor (const glqVec4 &rgba);
void			R_SetColor1 (float l);
void			R_SetColor2 (float l, float a);
void			R_SetColor3 (float r, float g, float b);
void			R_SetColor4 (float r, float g, float b, float a);

void			R_SetParameter (int index, float value);
void			R_SetParameters (const float parms[MAX_MATERIAL_PARMS]);

void			R_DrawStretchPic (float x, float y, float w, float h, float s1, float t1, float s2, float t2, horzAdjust_t horzAdjust, float horzPercent, vertAdjust_t vertAdjust, float vertPercent, material_t *material);
void			R_DrawStretchPicEx (float x, float y, float w, float h, float s1, float t1, float s2, float t2, float xShear, float yShear, float rotate, horzAdjust_t horzAdjust, float horzPercent, vertAdjust_t vertAdjust, float vertPercent, material_t *material);

void			R_DrawChar (float x, float y, float w, float h, int c, horzAdjust_t horzAdjust, float horzPercent, vertAdjust_t vertAdjust, float vertPercent, material_t *material);
void			R_DrawString (float x, float y, float w, float h, const char *string, const glqVec4 &color, bool forceColor, float xShadow, float yShadow, horzAdjust_t horzAdjust, float horzPercent, vertAdjust_t vertAdjust, float vertPercent, material_t *material);

// Cinematics can preserve their original aspect ratio, automatically
// letterboxing or pillarboxing if needed.
// The horizontal / vertical adjustment parameters are used to control the
// automatic coordinate scaling and aspect ratio correction on each axis
// separately.
// Does not allocate memory, so the image pointer must remain valid for the
// rest of the frame.
void			R_DrawCinematic (int x, int y, int w, int h, horzAdjust_t horzAdjust, float horzPercent, vertAdjust_t vertAdjust, float vertPercent, int handle, const byte *image, bool dirty, int width, int height, bool keepAspect);

// The render output can be cropped down to a subset of the real screen.
// To render to a texture, first set the crop size, then perform all desired
// rendering, then capture to a texture.
// The specified dimensions are in virtual SCREEN_WIDTH x SCREEN_HEIGHT
// coordinates unless forceDimensions is true.
// Users of the renderer will not know the actual pixel size of the area they
// are rendering to.
void			R_CropRenderSize (int width, int height, bool forceDimensions);
void			R_UnCropRenderSize ();

// A frame can consist of 2D drawing and potentially multiple 3D scenes
void			R_BeginFrame (int time);
void			R_EndFrame ();

// Debug visualization functions
void			R_DebugAxis (const glqVec3 &origin, const glqMat3 &axis, float size, bool depthTest, int allowInView);
void			R_DebugLine (const glqVec4 &color, const glqVec3 &start, const glqVec3 &end, bool depthTest, int allowInView);
void			R_DebugArrow (const glqVec4 &color, const glqVec3 &start, const glqVec3 &end, float size, bool depthTest, int allowInView);
void			R_DebugBounds (const glqVec4 &color, const glqBounds &bounds, bool depthTest, int allowInView);
void			R_DebugSphere (const glqVec4 &color, const glqSphere &sphere, bool depthTest, int allowInView);
void			R_DebugBox (const glqVec4 &color, const glqVec3 &origin, const glqMat3 &axis, const glqBounds &bounds, bool depthTest, int allowInView);
void			R_DebugCone (const glqVec4 &color, const glqVec3 &apex, const glqVec3 &direction, float apexRadius, float baseRadius, bool depthTest, int allowInView);
void			R_DebugCircle (const glqVec4 &color, const glqVec3 &origin, const glqVec3 &direction, float radius, int steps, bool depthTest, int allowInView);
void			R_DebugFrustum (const glqVec4 &color, const glqVec3 &origin, const glqMat3 &axis, float xMin, float xMax, float yMin, float yMax, float zNear, float zFar, bool depthTest, int allowInView);
void			R_DebugPolygon (const glqVec4 &color, int numPoints, const glqVec3 *points, bool fill, bool depthTest, int allowInView);
void			R_DebugText (const glqVec4 &color, bool forceColor, const glqVec3 &origin, float cw, float ch, const char *text, bool depthTest, int allowInView);

// Takes a screenshot
bool			R_TakeScreenshot (const char *name, bool gammaCorrect);

// Returns information about the OpenGL subsystem
glConfig_t		R_GetGLConfig ();

// This is called by the system when the main window gains or loses focus
void			R_Activate (bool active);

// Initializes the renderer subsystem.
// If all is false, the OpenGL subsystem will not be initialized, which is
// useful for flushing all data and resetting the state.
void			R_Init (bool all);

// Shuts down the renderer subsystem.
// If all is false, the OpenGL subsystem will not be shut down, which is useful
// for flushing all data and resetting the state.
void			R_Shutdown (bool all);


#endif	// __R_PUBLIC_H__